//
// Created by pzw on 24-3-1.
//

#ifndef QTTEST_HASHTABLE_H
#define QTTEST_HASHTABLE_H

#include <unordered_map>
#include <functional>
#include <set>
#include <vector>
#include <string>
#include <iostream>
#include <mutex>
#include <condition_variable>

/**
 * C++实现的java的HashTable
 *
 * @tparam Key   - key
 * @tparam Tp    - value
 * @tparam Hash  - hash值
 * @tparam Pred  - pred
 * @tparam Alloc - alloc
 */
template<
        typename Key,
        typename Tp,
        typename Hash = std::hash<Key>,
        typename Pred = std::equal_to<Key>,
        typename Alloc = std::allocator<std::pair<const Key, Tp>>
>
class HashTable {
private:
    /* 直接使用C++标准库的std::unordered_map */
    std::unordered_map<Key, Tp, Hash, Pred, Alloc> *map;
    /* HashTable是线程安全的数据操作 */
    std::mutex mutex{};

public:
    explicit HashTable(std::unordered_map<Key, Tp, Hash, Pred, Alloc> *map);
    ~HashTable();

public:/* 以下都是java的HashTable的函数 */
    Tp put(Key key, Tp value);
    void putAll(const std::unordered_map<Key, Tp> &m);
    Tp putIfAbsent(Key key, Tp value);
    void replaceAll(std::function<Tp(const Key &, const Tp &)> function);
    Tp get(Key key);
    bool containsKey(Key key);
    bool containsValue(Tp value);
    Tp remove(Key key);
    bool remove(Key key, Tp value);
    void clear();
    int size();
    bool isEmpty();
    std::set<Key> keySet();
    std::vector<Tp> values();
    std::set<std::pair<Key, Tp>> entrySet();
    Tp getOrDefault(Key key, Tp defaultValue);
    Tp operator[](Key key);
    void forEach(std::function<void(const Key &, const Tp &)> action);
    Tp replace(Key key, Tp value);
    bool replace(Key key, Tp oldValue, Tp newValue);
    Tp compute(Key key, std::function<Tp(const Key &, const Tp &)> remappingFunction);
    Tp computeIfAbsent(Key key, std::function<Tp(const Key &)> mappingFunction);
    Tp computeIfPresent(Key key, std::function<Tp(const Key &, const Tp &)> remappingFunction);
    bool remove(Key key, Key value);

};

int HashTable_main();


#endif //QTTEST_HASHTABLE_H
